vlwkaos' digital garden

Rust - closure, zero cost abs, variaous methods

Closure

anonymous functions that capture their environment a|nonymous = no name enclose

// || - pipes
// ()

fn do_it(input: i32) {
    
}

fn main() {
    // anonymous clousre, 함수처럼 쓸 수 있음
    let myclosure = |x: i32| println!("This is a closure");
    myclosure();


    let longcl = || {
        let my_num = 7;
        let o_num = 10;
        println!("{my_num}, {o_num}");
        my_num + o_num
    };

    let ma = longcl();
    println!("{ma}");
    
}

Zero cost abstractions

fn main(){
    let my = 9;
    let clousre = || println!("{my}"); // my에 대한 closure 제공

    // 아래처럼 체인을 해도 실제 동작시 속도는 닽고 compile 시간이 대신 좀 오래걸림
    // zero cost abstractions... js에서도 되나?
    .iter().map().filter().inspect();

    let my_vec = vec![8,9,10];

    let fourth = my_vec.get(3).unwrap_or_else(|| {
        if (my_vec.get(0).is_some()) {
            &my_vec[0]
        } else {
            &0
        }
    });

    println!("{fourth}");
}

map and for_each

  • collect가 없으면 Map { iter: Map {iter}} 이런식으로 아직 계산을 안한 상태 자료구조만 만들어짐
  • enumerate() // (0,2), (1,4), (2,6)
let numvec = ![2,4,6];
numvec.iter().enumerate().for_each(|index, x| {
    println!("{index}: {x}");
});

zipping iterators

위에서 for_each대신 map을 하면? collect 같은 타입

// i32, &str
let n = some_vec.into_iter().zip(other_vec.into_iter()).collect::<HashMap<_, _>>();
// {0, "zero"}, {1, "one"}...

char methods

  • .chars().count()
let big_string = "asldkfajlsdkfj is &str";
big_string.chars().for_each(|c| println!("{c}"))

filter, filter_map

  • map 으로 결과물을 구조로 만들고 filter로 거르고 다시 map해서 값으로 바꾸고..
  • 너무 길어서 filter_map 사용해서 monad로 바로
let all_the_ceos = company_vec.into_iter().filter_map(|company| company.ok());

ok_or, ok_or_else

let u = vec!["1.2", "Nine point nine"];

let actualnum = u
    .into_iter()
    .filter_map(|i| i.parse().ok()) // Ok(num) / Err(err)
    .collect::<Vec<f32>>();
  • ok_or("No CEO found") -> Result로 바꾸고 error 메세지로 들어감
  • ok_or_else(|| { 클로져 형태로 다른 동작을 할 수 있다.
  • });
iter().for_each(|cpy| {
    results_vec.push(cpy.get_ceo().ok_or_else(|| {
        // 복잡한 로직으로 에러 반환
        let err = format!("No CEO found for {}", cpy.name);
        err
    }))
})

Referred in

Rust - closure, zero cost abs, variaous methods